package com.merry.api.validator;

import com.merry.api.constant.ApiConstant;
import com.merry.api.entity.ApiUserInfoEntity;
import com.merry.api.mapper.ApiMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * API接口的头信息验证模块，首先验证的。
 */
@Service
@Order(1)
public class ApiHeadValidator implements ApiValidator {

    //时间差最大的时间，默认为 5 分钟
    @Value("${api.max_interval_minute}")
    private Integer maxIntervalMinute;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private ApiMapper mapper;

    /**
     * 头信息的验证模块。
     */
    @Override
    public boolean verify(HttpServletRequest request) throws Exception {
        //用户id
        String paasId = request.getHeader(ApiConstant.PASSID);
        //时间戳
        String timestamp = request.getHeader(ApiConstant.TIMESTAMP);
        //采用SHA1加密之后的结果
        String signature = request.getHeader(ApiConstant.SIGNATURE);
        //当前时间戳，以秒为单位。
        long currentTimeStamp = System.currentTimeMillis() / 1000;
        //如果这三个参数为空，
        if (StringUtils.isEmpty(paasId) || StringUtils.isEmpty(timestamp) || StringUtils.isEmpty(signature)) {
            throw new Exception("缺少头部信息！");
        }
        //判断时间差
        if ((currentTimeStamp - Long.parseLong(timestamp)) / 60 > maxIntervalMinute) {
            throw new Exception("时间信息过期了");
        }
        // 根据paasid获取对应的token及用户信息
        ApiUserInfoEntity apiUser = (ApiUserInfoEntity) redisTemplate.boundHashOps(ApiConstant.REDIS_KEY_API_USER).get(paasId);
        if (apiUser == null) {
            apiUser = mapper.queryApiUserById(paasId);
            if (apiUser != null) {
                redisTemplate.boundHashOps(ApiConstant.REDIS_KEY_API_USER).put(paasId, apiUser);
            } else {
                throw new Exception("用户id错误！");
            }
        }
        // 验证签名加密串是否正确，忽略大小写验证
        if (!signature.equals(apiUser.getToken())) {
            throw new Exception("密码错误！");
        }
        return true;
    }
}
